/**
 *
 *		jsColorPallet - very basic color pallet
 *		jsColorPallet is a very basic color pallet that is bound to text fields in your document.
 *		onFocus of the selected text field the selected color pallet will apear allowing the user
 *		to select a color. There are multipul color pallets the user to select colors from.
 *
 *		Thanks to Dynarch.com for a portion of code barrowed. - Element Positioning
 *
 *		A portion Copyright 2003-2006 (c) Dynarch.com
 *		The rest Copyright 2006 (c) Skeletal Design, Inc
 *
 *		@version	v1.2 2007/04/06
 *
 */


jsColorPallet = Class.create();
jsColorPallet.prototype = {
	initialize: function(options) {
		/**
		 *	Initialization of jsColorPallet
		 *	Bind, Creates, and Draws out all the color pallets
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	title			string	optional		Title of the color pallet
		 *	@param	forms			array					An array of elements, id, or an element that represents the form(s) that you would like jsColorPallet to bind to
		 *	@param	fields			array/string/element	An array of elements, id, or an element that represents all the form elements that you wish jsColorPallet to appear on				
		 *	@param	bindingElement	string/object			The element to append the color pallet to
		 *	@param	extendedPallets	array					Array of custom color pallets to add to the collection
		 *	@param	debug			boolean					Turns debug mode on or off. Use only in FireFox with the Firebug plugin.
		 *	@date	2007/05/19
		 */
		
		this.options = {
			title: 'jsColorPallet',
			forms: null,
			fields: null,
			bindingElement: null,
			extendedPallets: new Array(),
			callback: null,
			debug: false
		}
		Object.extend(this.options, options);
		
		this.currentFormField = {					// The current/last field to be evaluated to display the color pallet
			field: null,
			prop: null
		}
		this.palletController = {					// Object to manage and store each color pallet
			currentPallet:0, 						// Current selected Color Pallet
			currentTitle: this.options.title,
			pallets: new Array()					// Array of all the Color Pallet Elements
		}
		this.colorPalletCollection = new Array();
		this.colorPalletCollection.push(jsColorPallet1);
		this.colorPalletCollection.push(jsColorPallet2);
		
		
		this._drawAllPallets();
		this._bindForms();	// Bind the jsColorPallet to all the forms
	},
	_drawAllPallets: function(){
		this.colorPalletCollection.each(
			function(iter){
				this.addColorPallet(iter);
			}.bind(this)
		);
		
		this.options.extendedPallets.each(
			function(iter){
				this.addColorPallet(iter);
			}.bind(this)
		);
	},
	_bindForms: function(){
		/**
		 *	Binds the color pallet to each form element
		 *	Goes throught the complete form and binds the color pallet to each form element
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	formBind	string	form id of the form to bind the color pallet to
		 *	@date	2006/09/15
		 */
		$A(this.options.forms).each(
			function(iter){
				this.addForm(iter);
			}.bind(this)
		);
	},
	addForm: function(form){
		var elements = $(form).getElements();
		elements.each(
			function(iterElements){
				Event.observe(
					iterElements,
					'focus',
					function(){
						this.displayPallet(iterElements);
					}.bindAsEventListener(this)
				);
			}.bind(this)
		)
	},
	addColorPallet: function(pallet){
		/**
		 *	Create and Addes each Color Pallet to the DOM and Controller
		 *	Take a color pallet definition and addes it to the DOM and the Color Pallet Controller
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	title	string optional	Value to initial set as the title of the color pallet
		 *	@return	var	desc
		 *	@date	2006/09/15
		 */

		var thisColorPallet = document.createElement('div');
		thisColorPallet.setAttribute('id','colorPallet'+ this.palletController.pallets.length +'');
		thisColorPallet.style.display = 'none';
		thisColorPallet.style.position = 'absolute';
		thisColorPallet.style.width = '202px';

		var colorPalletTable = document.createElement('table');
		colorPalletTable.className = 'colorPalletTable';
		colorPalletTable.cellPadding = '0';
		colorPalletTable.cellSpacing = '0';

		var colorPalletTablebody = document.createElement('tbody');

		var colorPalletTableRow = document.createElement('tr');

		var colorPalletTableCell = document.createElement('td');
		colorPalletTableCell.setAttribute('colSpan', pallet[0].length);

		var colorPalletHeader = document.createElement('div');
		colorPalletHeader.className = 'colorPalletHeader';

		var colorPalletControlClose = document.createElement('div');
		colorPalletControlClose.className = 'colorPalletControl';

		var closeLink = document.createElement('a');
		closeLink.href = '#';
		closeLink.title = 'Close';
		closeLink.onclick = function(){this.closePallet(); return false;}.bind(this)

		var closeLinkImage = document.createElement('img');
		closeLinkImage.src = 'close.gif';
		closeLinkImage.border = '0';

		closeLink.appendChild(closeLinkImage);
		colorPalletControlClose.appendChild(closeLink);
		colorPalletHeader.appendChild(colorPalletControlClose);

		var colorPalletControlChange = document.createElement('div');
		colorPalletControlChange.className = 'colorPalletControl';

		var changeLink = document.createElement('a');
		changeLink.href = '#';
		changeLink.title = 'Change Color Pallet';
		
		var changeLinkFunc = function(){this.nextPallet(); return false;}.bind(this)
		changeLink.onclick = changeLinkFunc;

		var changeLinkImage = document.createElement('img');
		changeLinkImage.src = 'down.gif';
		changeLinkImage.border = '0';

		changeLink.appendChild(changeLinkImage);
		colorPalletControlChange.appendChild(changeLink);
		colorPalletHeader.appendChild(colorPalletControlChange);

		var colorPalletTitle = document.createElement('div');
		colorPalletTitle.style.cssFloat = 'left';
		colorPalletTitle.className = 'colorPalletTitle';
		colorPalletTitle.innerHTML = this.palletController.currentTitle;
		colorPalletHeader.appendChild(colorPalletTitle);

		var clearDiv = document.createElement('div');
		clearDiv.style.clear = 'both';

		colorPalletHeader.appendChild(clearDiv);
		colorPalletTableCell.appendChild(colorPalletHeader);
		colorPalletTableRow.appendChild(colorPalletTableCell);
		colorPalletTablebody.appendChild(colorPalletTableRow);
		
		//Draw each row of the Color Pallet
		for(h = 0; h < pallet.length; h++){
			var colorRow = document.createElement('tr');

			for(c = 0; c < pallet[h].length; c++){
				var colorCell = document.createElement('td');
				colorCell.style.backgroundColor = pallet[h][c].hex;

				var colorCellLink = document.createElement('a');
				colorCellLink.onclick = function(){this.returnColor(arguments[0]); return false;}.bind(this,pallet[h][c].hex)
				colorCellLink.innerHTML = '&nbsp;';
				colorCellLink.className = 'colorPallet';
				colorCellLink.title = pallet[h][c].hex;
				colorCellLink.href = '#';

				colorCell.appendChild(colorCellLink);
				colorRow.appendChild(colorCell);
			}
			colorPalletTablebody.appendChild(colorRow);
		}
			//Draw the end of the Color Pallet

		colorPalletTable.appendChild(colorPalletTablebody);
	 	thisColorPallet.appendChild(colorPalletTable);
	 	
		 if(this.options.bindingElement)
		 	$(this.options.bindingElement).appendChild(thisColorPallet);
		 else
		 	document.body.appendChild(thisColorPallet);
		 	
		 this.palletController.pallets.push($('colorPallet'+ this.palletController.pallets.length +''));
	},
	closePallet: function(){
		this._togglePallet(false);
	},
	nextPallet: function(pallet){
		if(!pallet){
			var next = this.palletController.currentPallet + 1;
			if(next >= this.palletController.pallets.length)
				next = 0;
			this._debugMessage('Next: '+ next +' Length: '+ this.palletController.pallets.length);
			this._togglePallet(false);
			this.displayPallet(this.currentFormField.field, next);
		} else {
			this._debugMessage('Next: '+ pallet +' Length: '+ this.palletController.pallets.length);
			if(pallet >= this.palletController.pallets.length){
				this._debugMessage('Selected Pallet does not exist in the collection.');
				return;
			}
			this._togglePallet(false);
			this.displayPallet(this.currentFormField.field, pallet);
		}
	},
	//Displays the Pallet reletive to the Field in question
	displayPallet: function(field, pallet){
		/**
		 *	Display the color pallets
		 *	Get the current field in focus, possitions the color pallet to that field
		 *	and then displays the color pallet.
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	field	object	An object of the current working form field
		 *	@param	pallet	integer	optional	The id of the color pallet you would like to use
		 *	@date	2006/09/15
		 */
		
		var prop = this._getElementProperties(field.id);

		if(!prop){
			this._togglePallet(false);
			return;
		}

		
		this._togglePallet(false);
		//Set the Global Ref. Var to the current working field
		this.currentFormField.field = $(field);
		this.currentFormField.prop = prop;

		if(pallet || pallet === 0){
			if(pallet >= this.palletController.pallets.length){
				this._debugMessage('Selected Pallet does not exist in the collection.');
				return;
			} else {
				this.palletController.currentPallet = pallet;
			}
		}
		
		if(this.currentFormField.prop.title){
			this.changeTitle(this.currentFormField.prop.title);
		} else {
			this.changeTitle(this.options.title);
		}
		this.positionPallet();
		this._togglePallet(true);
	},
	positionPallet: function(){
		var workingFieldOffset = this.currentFormField.field.scrollWidth;
		var textFieldPos = this._getAbsolutePos(this.currentFormField.field);
		
		this.palletController.pallets[this.palletController.currentPallet].style.top = (textFieldPos.y) + 'px';
		this.palletController.pallets[this.palletController.currentPallet].style.left = (textFieldPos.x + workingFieldOffset) + 'px';
	},
	_togglePallet: function(display){
		/**
		 *	toggle the displaying of the color pallet
		 *	Check the current status of the color pallet and shows or hides it based on that
		 *	If what is past the color pallet will perform that function
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	display	string	optional	Force color pallet to be shown 'show' or hiden 'hide'
		 *	@date	2006/09/15
		 */

		if(display){
			this.palletController.pallets[this.palletController.currentPallet].style.display = '';
		} else{
			this.palletController.pallets[this.palletController.currentPallet].style.display = 'none';
		}
	},
	_getAbsolutePos: function(el) {
		/**
		 *	gets the position of the given element
		 *	Gets the position of the passed element. And returns that value
		 *	Function was barrowed from Dynarch.com's jsCalendar program
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	el	object	Object of the element you want to get position of
		 *	@return	r	object	returns x 'r.x', y 'r.y' of the element given
		 *	@date	2006/09/15
		 */
		  var SL = 0, ST = 0;
		  var is_div = /^div$/i.test(el.tagName);
		  if (is_div && el.scrollLeft)
			   SL = el.scrollLeft;
		  if (is_div && el.scrollTop)
			   ST = el.scrollTop;
		  var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
		  if (el.offsetParent) {
			   var tmp = this._getAbsolutePos(el.offsetParent);
			   r.x += tmp.x;
			   r.y += tmp.y;
		  }
		  return r;
	 },
	 //Return the selected color to the field in question, and hide the pallet
	 returnColor: function(color){
		/**
		 *	returns the picked color
		 *	Returns ths picked color back to the currently focused element
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	anchorField	string	hex color to return back to the current field
		 *	@date	2006/09/15
		 */
		if(color != '' && color != null){
			this.currentFormField.field.value = color;
		}
		if(this.currentFormField.prop.callback){
			this.currentFormField.prop.callback(color);
		}
		if(this.options.callback){
			this.options.callback(color);
		}
		//Hide pallet
		this._togglePallet(false);
	 },
	 changeTitle: function(title){
		/**
		 *	Changes the title of all the color pallets
		 *	Goes throught and changes all the titles on all the color pallets
		 *
		 *	@author	NerdyNick	nick@skeletaldesign.com
		 *	@param	title	string	title you would like to set the color pallet to
		 *	@date	2006/09/15
		 */
		this.palletController.currentTitle = title;
		var titles = $$('div.colorPalletTitle');
		 for(i=0;i < titles.length; i++){
		 	titles[i].innerHTML = title;
		 }
	 },
	 _debugMessage: function(message){
	 	if(this.options.debug)
	 		console.debug(message);
	 },
	 _getElementProperties: function(id){
	 	var prop = false;
	 	for(i=0;i<this.options.fields.length;i++){
			if($(this.options.fields[i].field).id == id){
				prop = this.options.fields[i];
				break;
			}
		}
		return prop;
	 }
}